// components/common/picture-select/index.js
import componentBehaviors from '../../../behaviors/component';
import { COMPONENT_OPTIONS } from '../../../constants/common';
import { chooseImage, checkImageSecurity, tipToast, getSysInfo, getImageInfo } from '../../../common/env';
import { uploadImage } from '../../../common/cos';
import { DEFAULT_BG_LIST } from '../../../constants/common';

const defaultData = {
    isShowCropper: false,
    // 初始化的宽高
    cropperInitW: 750,
    cropperInitH: 750,
    // 动态的宽高
    cropperW: 750,
    cropperH: 750,
    // 动态的left top值
    cropperL: 0,
    cropperT: 0,

    transL: 0,
    transT: 0,

    // 图片缩放值
    scaleP: 0,
    imageW: 0,
    imageH: 0,

    // 裁剪框 宽高
    cutL: 0,
    cutT: 0,
    cutB: 0,
    cutR: 0,

    qualityWidth: '',
    innerAspectRadio: 750 / getSysInfo().windowWidth,

    C_CONSTANTS: {
        SCREEN_WIDTH: 750,
        PAGE_X: 0, // 手按下的x位置
        PAGE_Y: 0, // 手按下y的位置
        PR: getSysInfo().pixelRatio, // dpi
        T_PAGE_X: {}, // 手移动的时候x的位置
        T_PAGE_Y: {}, // 手移动的时候Y的位置
        CUT_L: 0, // 初始化拖拽元素的left值
        CUT_T: 0, // 初始化拖拽元素的top值
        CUT_R: 0, // 初始化拖拽元素的
        CUT_B: 0, // 初始化拖拽元素的
        CUT_W: 0, // 初始化拖拽元素的宽度
        CUT_H: 0, //  初始化拖拽元素的高度
        IMG_RATIO: 0, // 图片比例
        IMG_REAL_W: 0, // 图片实际的宽度
        IMG_REAL_H: 0, // 图片实际的高度
        IMG_TYPE: '', //图片的格式
        DRAFG_MOVE_RATIO: 750 / getSysInfo().windowWidth //移动时候的比例
    }
};
let data = {};

try {
    data = JSON.parse(JSON.stringify(defaultData));
} catch (e) {
    console.error('数据处理出错: ', e)
};

Component({
    behaviors: [componentBehaviors],
    options: {
        ...COMPONENT_OPTIONS,
    },
    properties: {
        // 模式 选择、上传
        mode: {
            type: String,
            value: 'select', // select|upload
        },
        title: {
            type: String,
            value: '上传图片'
        },
        // 业务类型(上传用)
        bizType: {
            type: String,
            value: 'img', // img|user|brand|activity
        },
        // 可选图片列表
        pictureList: {
            type: Array,
            value: DEFAULT_BG_LIST,
        },
        // 默认选中的
        defaultSelect: {
            type: String,
            value: '',
        },
        // 是否开启裁剪
        isCrop: {
            type: Boolean,
            value: false,
        },
        // 是否是圆形
        isCircleCrop: {
            type: Boolean,
            value: false,
        },
        // 裁剪比例
        cropRatio: {
            type: Number,
            value: 1,
        },
        // 是否是固定比例
        isFixedRatio: {
            type: Boolean,
            value: false,
        },
    },


    // lifetimes: {
    //     // 生命周期函数，可以为函数，或一个在methods段中定义的方法名
    //     attached: function () {
    //         if (this.data.defaultSelect) {
    //             this.setData({
    //                 selectValue: this.data.defaultSelect,
    //             });
    //         }
    //     },
    // },
    observers: {
        'defaultSelect': function (val) {
            val && this.setData({ selectValue: val });
        },
    },
    data: {
        selectValue: '',
        isShowCropper: false,
        imageSrc: '',
        ...data,
    },
    methods: {
        clearTouchAction: function () {},
        // 切换选择
        selectChange: function (event) {
            const { value } = event.currentTarget.dataset;
            this.setData({
                selectValue: value,
            });
            this.triggerEvent('change', value);
        },
        // 选择图片
        selectPicture: async function () {
            const pathList = await chooseImage();
            const filePath = pathList[0];
            const flag = await checkImageSecurity(filePath);
            const { isCrop } = this.data;
            if (flag) {
                this.setData({
                    imageSrc: filePath,
                    isShowCropper: isCrop ? true : false,
                }, () => {
                    isCrop ? this.loadImage() : this.uploadImageAndReturn(filePath);
                });
            } else {
                tipToast('请确认图片合法、合规');
            }
        },
        async uploadImageAndReturn(filePath) {
            const { bizType } = this.data;
            const { url } = await uploadImage(bizType, filePath);
            this.triggerEvent('change', url);
        },
        loadImage() {
            let {
                cropRatio,
                imageSrc
            } = this.data;
            let {
                IMG_REAL_W,
                IMG_REAL_H,
                IMG_RATIO,
                SCREEN_WIDTH,
                IMG_TYPE
            } = this.data.C_CONSTANTS;
            getImageInfo(imageSrc).then(res => {
                IMG_REAL_W = res.width;
                IMG_REAL_H = res.height;
                IMG_RATIO = IMG_REAL_W / IMG_REAL_H;
                IMG_TYPE = res.type === 'png' ? 'png' : 'jpg';
                // 根据图片的宽高显示不同的效果   保证图片可以正常显示
                let temp = {};
                let cropperData = {};
                if (IMG_RATIO >= 1) {
                    cropperData = {
                        cropperW: SCREEN_WIDTH,
                        cropperH: SCREEN_WIDTH / IMG_RATIO,
                        // 初始化left right
                        cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
                        cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2)
                    }
                    if (cropRatio > 1) {
                        temp = {
                            cutL: (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2,
                            cutT: (SCREEN_WIDTH / IMG_RATIO - SCREEN_WIDTH / IMG_RATIO / cropRatio) / 2,
                            cutR: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2 - SCREEN_WIDTH / IMG_RATIO,
                            cutB: SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - SCREEN_WIDTH / IMG_RATIO / cropRatio) / 2 - SCREEN_WIDTH / IMG_RATIO / cropRatio
                        }
                    } else {
                        temp = {
                            cutT: 0,
                            cutB: 0,
                            cutL: (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO * cropRatio) / 2,
                            cutR: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO * cropRatio) / 2 - SCREEN_WIDTH / IMG_RATIO * cropRatio
                        }
                    }
                } else {
                    cropperData = {
                        cropperW: SCREEN_WIDTH * IMG_RATIO,
                        cropperH: SCREEN_WIDTH,
                        // 初始化left right
                        cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),
                        cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2)
                    }
                    if (cropRatio > 1) {
                        temp = {
                            cutL: 0,
                            cutR: 0,
                            cutT: (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO / cropRatio) / 2,
                            cutB: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO / cropRatio) / 2 - SCREEN_WIDTH * IMG_RATIO / cropRatio
                        }
                    } else {
                        temp = {
                            cutL: (SCREEN_WIDTH * IMG_RATIO - SCREEN_WIDTH * IMG_RATIO * cropRatio) / 2,
                            cutR: SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO - SCREEN_WIDTH * IMG_RATIO * cropRatio) / 2 - SCREEN_WIDTH * IMG_RATIO * cropRatio,
                            cutT: (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2,
                            cutB: SCREEN_WIDTH - (SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2 - SCREEN_WIDTH * IMG_RATIO
                        }

                    }
                }
                this.setData({
                    C_CONSTANTS: Object.assign({}, this.data.C_CONSTANTS, {
                        IMG_REAL_W,
                        IMG_REAL_H,
                        IMG_RATIO,
                        IMG_TYPE
                    }),
                    isShowCropper: true,
                    // 图片缩放值
                    scaleP: IMG_REAL_W / SCREEN_WIDTH,
                    qualityWidth: IMG_REAL_W,
                    innerAspectRadio: IMG_RATIO,
                    ...temp,
                    ...cropperData
                })
            });
        },
        contentStartMove(e) {
            this.setData({
                'C_CONSTANTS.PAGE_X': e.touches[0].pageX,
                'C_CONSTANTS.PAGE_Y': e.touches[0].pageY
            })
        },
        // 拖动时候触发的touchMove事件
        contentMoveing(e) {
            let {
                PAGE_X,
                PAGE_Y,
                DRAFG_MOVE_RATIO
            } = this.data.C_CONSTANTS;
            let {
                cutL,
                cutR,
                cutT,
                cutB
            } = this.data;
            let dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
            let dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
            // 左移
            if (dragLengthX > 0) {
                if (cutL - dragLengthX < 0) dragLengthX = cutL
            } else {
                if (cutR + dragLengthX < 0) dragLengthX = -cutR
            }

            if (dragLengthY > 0) {
                if (cutT - dragLengthY < 0) dragLengthY = cutT
            } else {
                if (cutB + dragLengthY < 0) dragLengthY = -cutB
            }
            this.setData({
                cutL: cutL - dragLengthX,
                cutT: cutT - dragLengthY,
                cutR: cutR + dragLengthX,
                cutB: cutB + dragLengthY,
                'C_CONSTANTS.PAGE_X': e.touches[0].pageX,
                'C_CONSTANTS.PAGE_Y': e.touches[0].pageY
            });
        },
        // 设置大小的时候触发的touchStart事件
        dragStart(e) {
            let {
                cutL,
                cutR,
                cutT,
                cutB
            } = this.data;
            this.setData({
                C_CONSTANTS: Object.assign({}, this.data.C_CONSTANTS, {
                    T_PAGE_X: e.touches[0].pageX,
                    T_PAGE_Y: e.touches[0].pageY,
                    CUT_L: cutL,
                    CUT_R: cutR,
                    CUT_B: cutB,
                    CUT_T: cutT
                })
            })

        },
        // 设置大小的时候触发的touchMove事件
        dragMove(e) {
            let dragType = e.target.dataset.drag
            let {
                cropRatio,
                cropperW,
                cropperH,
                cutL,
                cutT,
                cutR,
                cutB,
                isFixedRatio,
            } = this.data;
            let {
                CUT_R,
                CUT_L,
                CUT_T,
                CUT_B,
                T_PAGE_X,
                T_PAGE_Y,
                DRAFG_MOVE_RATIO
            } = this.data.C_CONSTANTS;
            let dragLength;
            switch (dragType) {
                case 'right':
                    dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
                    if (CUT_R + dragLength < 0) dragLength = -CUT_R
                    cutR = CUT_R + dragLength;
                    if (isFixedRatio) {
                        cutT = CUT_T + dragLength / cropRatio;
                    }
                    if (cutR < 0 || cutT < 0 || cutT > cropperH || cutR > cropperW) return;
                    break;
                case 'left':
                    dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
                    if (CUT_L - dragLength < 0) dragLength = CUT_L
                    if ((CUT_L - dragLength) > (this.data.cropperW - this.data.cutR)) dragLength = CUT_L - (this.data.cropperW - this.data.cutR)
                    cutL = CUT_L - dragLength;
                    if (isFixedRatio) {
                        cutT = CUT_T - dragLength / cropRatio;
                    }
                    if (cutL < 0 || cutT < 0 || cutT > cropperH || cutL > cropperW) return;
                    break;
                case 'top':
                    dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
                    if (CUT_T - dragLength < 0) dragLength = CUT_T
                    if ((CUT_T - dragLength) > (this.data.cropperH - this.data.cutB)) dragLength = CUT_T - (this.data.cropperH - this.data.cutB)
                    cutT = CUT_T - dragLength;
                    if (isFixedRatio) {
                        cutR = CUT_R - dragLength * cropRatio;
                    }
                    break;
                case 'bottom':
                    dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
                    if (CUT_B + dragLength < 0) dragLength = -CUT_B
                    cutB = CUT_B + dragLength;
                    if (isFixedRatio) {
                        cutR = CUT_R + dragLength * cropRatio;
                    }
                    if (cutR < 0 || cutT < 0 || cutT > cropperH || cutR > cropperW) return;
                    break;
                default:
                    '';
            }
            this.setData({
                cutL,
                cutT,
                cutR,
                cutB
            });
        },
        contentTouchEnd() {},
        // 获取图片
        confirmCropper() {
            const { isCircleCrop } = this.data;;
            if (isCircleCrop) {
                this.circleCrop()
            } else {
                this.normalCropper();
            }
        },

        normalCropper() {
            let {
                imageSrc,
                cropperW,
                cropperH,
                cutL,
                cutT,
                cutR,
                cutB
            } = this.data;
            let {
                IMG_REAL_W,
                IMG_REAL_H,
                IMG_TYPE
            } = this.data.C_CONSTANTS;
            // 将图片写入画布
            const ctx = wx.createCanvasContext('cropper', this)
            ctx.drawImage(imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
            ctx.draw(true, () => {
                // 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.data.cutT / _this.data.cropperH) * (_this.data.imageH / pixelRatio)
                let canvasW = ((cropperW - cutL - cutR) / cropperW) * IMG_REAL_W
                let canvasH = ((cropperH - cutT - cutB) / cropperH) * IMG_REAL_H
                let canvasL = (cutL / cropperW) * IMG_REAL_W
                let canvasT = (cutT / cropperH) * IMG_REAL_H
                wx.canvasToTempFilePath({
                    x: canvasL,
                    y: canvasT,
                    width: canvasW,
                    height: canvasH,
                    destWidth: canvasW,
                    destHeight: canvasH,
                    fileType: IMG_TYPE || 'jpg',
                    canvasId: 'cropper',
                    success: (res) => {
                        //图片裁剪成功
                        this.cancelCropper();
                        this.uploadImageAndReturn(res.tempFilePath);
                        // this.triggerEvent('cropperDone', {
                        //     src: res.tempFilePath,
                        //     cropperData: {
                        //         x: canvasL,
                        //         y: canvasT,
                        //         width: canvasW,
                        //         height: canvasH
                        //     }
                        // })
                    },
                    fail: err => {
                        // this.triggerEvent('cropperFail', err)
                        this.cancelCropper();
                        tipToast('裁剪失败，请重试');
                    }
                }, this);
            })
        },

        circleCrop() {
            let {
                imageSrc,
                cropperW,
                cropperH,
                cutL,
                cutT,
                cutR,
                cutB
            } = this.data;
            let {
                IMG_REAL_W,
                IMG_REAL_H,
                IMG_TYPE
            } = this.data.C_CONSTANTS;
            // 将图片写入画布
            const ctx = wx.createCanvasContext('cropper', this)
            let canvasW = ((cropperW - cutL - cutR) / cropperW) * IMG_REAL_W
            let canvasL = (cutL / cropperW) * IMG_REAL_W
            let canvasT = (cutT / cropperH) * IMG_REAL_H

            this.setData({
                canvasW: canvasW,
                canvasH: canvasW
            }, () => {
                ctx.arc(canvasW / 2, canvasW / 2, canvasW / 2, 0, 2 * Math.PI);
                ctx.clip();
                ctx.drawImage(imageSrc, canvasL, canvasT, canvasW, canvasW, 0, 0, canvasW, canvasW);
                ctx.draw(true, () => {
                    wx.canvasToTempFilePath({
                        fileType: IMG_TYPE || 'jpg',
                        canvasId: 'cropper',
                        success: (res) => {
                            //图片裁剪成功
                            this.cancelCropper();
                            this.uploadImageAndReturn(res.tempFilePath);
                            // this.triggerEvent('cropperDone', {
                            //     src: res.tempFilePath,
                            //     cropperData: {
                            //         x: canvasL,
                            //         y: canvasT,
                            //         width: canvasW,
                            //         height: canvasW
                            //     }
                            // })
                        },
                        fail: err => {
                            this.triggerEvent('cropperFail', err)
                        }
                    }, this);
                })
            })
        },

        cancelCropper() {
            let originData = {}
            try {
                originData = JSON.parse(JSON.stringify(defaultData))
            } catch (e) {};

            this.setData({
                ...originData,
                isShowCropper: false,
            });
        }
    }
})